﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Automation;
using Compiled_Tests.AutomationAbstractions;

using Tedds_Tool.Instructions;
using CommonInterfaces.Models;
using StandardScriptItems.SimpleControls;
using LEET.CommonInterfaces.Factories;
using LEET.CommonInterfaces.Automation;
using LEET.LEETCommon.AutomationAbstractions;
using LEET.CommonInterfaces.Models;
using LEET.LEETCommon.Model;
using System.Windows;
using LEET.StandardModuals.Instructions.Actions;

namespace Tedds_Tool.Automatables
{
    public class ValueSetable : ILEETActionModual, IHackable
    {
        public AutomationElementEventListener CreateListener(IObservableWidget elem, IRegistryAccessor reg)
        {
            return new EventListener(elem, reg, hacks);
        }

        public bool CanCompile(string instruction)
        {
            try
            {
                String[] parts = Instruction.ParseInstruction(instruction);
                return parts.Count() >= 2 && "ACTION".Equals(parts[0]) && TypeName.Equals(parts[1]);
            }
            catch (InvalidInstructionException)
            {
                return false;
            }
        }

        public IInstruction CreateInstruction(string instruction)
        {
            return new SetVal(Instruction.ParseInstruction(instruction));
        }

        public void LoadHack(ILEETHackModual modual)
        {
            hacks.Add(modual);
        }

        IList<ILEETHackModual> hacks = new List<ILEETHackModual>();
        
        private class EventListener : AutomationElementEventListenerBase
        {

            AutomationPropertyChangedEventHandler handler;
            private IRegistryAccessor registry;
            IList<ILEETHackModual> hacks;

            public EventListener(IObservableWidget target, IRegistryAccessor reg, IList<ILEETHackModual> hacks)
            {

                this.hacks = hacks;
                this.RootTarget = target;
                this.registry = reg;
                Listening = false;
                try
                {
                    handler = new AutomationPropertyChangedEventHandler(CatchEvent);
                    registry.RegisterEventHandler(ValuePattern.ValueProperty, RootTarget.ae, handler);
                    registry.RegisterEventHandler(ValuePattern.IsReadOnlyProperty, RootTarget.ae, handler);
                    Listening = true;
                }
                catch (ArgumentException) { }
            }

            public override void Listen(IObservableWidget widget, String property, String newValue)
            {
                String value = newValue;
                IUIPath element = widget.GetUIAHierarchy(RootTarget);

                bool handled = false;
                foreach (ILEETHackModual modual in hacks)
                {
                    if (value.StartsWith("_____" + modual.HackFlag + ":"))
                    {
                        Delagate( new Event_Pair("ACTION | " + modual.ActionName + " | " + element.ToString() + " | " + modual.Instruction(value)) );
                        handled = true;
                        break;
                    }
                }
                
                //If this event wont be handled by TextSetable...
                if (!handled && !widget.HasPattern(TextPattern.Pattern) && !widget.IsReadOnly)
                {
                    Delagate(new Event_Pair("ACTION\t| SETVAL | " + element.ToString() + " | " + value));
                }
            }

            public override void Dispose()
            {
                registry.RemoveEventHandler(ValuePattern.ValueProperty, RootTarget.ae, handler);
                registry.RemoveEventHandler(ValuePattern.IsReadOnlyProperty, RootTarget.ae, handler);
                base.Dispose();
            }

        }



        public void Initialize()
        {
        }

        public string TypeName
        {
            get { return "SETVAL"; }
        }

       

        public FrameworkElement CreateScriptItemDetails(LEET.CommonInterfaces.Nil onUpdate, IEnumerable<string> processes, IElementState state)
        {
            ElementStateComboBox elem = new ElementStateComboBox(state);
            elem.Filter(delegate(String var)
            {
                return state.Property(var).Contains("ValuePattern.Current.Value"); 
            });
            ScriptItemArgument arg1 = new ScriptItemArgument(elem, "-- Value? --");
            return arg1;
        }
    }
}
